/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package LogicaNegocio.Controlador;

import AccesoDatos.Persistencia.Manager.ManagerArea;
import AccesoDatos.Persistencia.Manager.ManagerAutor;
import AccesoDatos.Persistencia.Manager.ManagerInformes;
import AccesoDatos.Persistencia.Manager.ManagerLibro;
import AccesoDatos.Persistencia.Manager.ManagerPalabra;
import GUI.Bibliotecario.AdminLibros.PanelRegistrarLibro;
import LogicaNegocio.Biblioteca.Area;
import LogicaNegocio.Biblioteca.Autor;
import LogicaNegocio.Biblioteca.Editorial;
import LogicaNegocio.Biblioteca.Libro;
import LogicaNegocio.Biblioteca.PalabraClave;
import LogicaNegocio.Validacion.VBiblioteca;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityExistsException;
import javax.persistence.RollbackException;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

/**
 * Esta clase en java permite controlar el registro de libros
 * en el sistema BiblioSoft.
 *
 * @author sebaxtian
 * Archivo: ControlRegistrarLibro.java
 * @version 1.0
 * Fecha: dom may 16 16:55:05 COT 2010
 */


public class ControlRegistrarLibro {

    //Atributos de clase
    private PanelRegistrarLibro panelRegistrarLibro;
    private ManagerInformes gestorInformes;
    private ManagerAutor gestorAutor;
    private ManagerArea gestorArea;
    private ManagerPalabra gestorPalabra;
    private ManagerLibro gestorLibro;
    private Date fechaPublicacion;


    public ControlRegistrarLibro(PanelRegistrarLibro panelRegistrarLibro) {
        this.panelRegistrarLibro = panelRegistrarLibro;
        gestorInformes = new ManagerInformes();
        gestorAutor = new ManagerAutor();
        gestorArea = new ManagerArea();
        gestorPalabra = new ManagerPalabra();
        gestorLibro = new ManagerLibro();
        fechaPublicacion = null;
    }


    public void buscarAutor() {
        int codigo = -1;
        if(panelRegistrarLibro.textFielCodigoAutorBuscar.getText() != null && !panelRegistrarLibro.textFielCodigoAutorBuscar.getText().equals("")){
                 codigo = Integer.parseInt(panelRegistrarLibro.textFielCodigoAutorBuscar.getText());
        }
        String primerApellido = panelRegistrarLibro.textFieldPrimerApellidoAutorBuscar.getText().equals("") ? null : panelRegistrarLibro.textFieldPrimerApellidoAutorBuscar.getText();
        String primerNombre = panelRegistrarLibro.textFieldPrimerNombreAutorBuscar.getText().equals("") ? null : panelRegistrarLibro.textFieldPrimerNombreAutorBuscar.getText();
        String segundoApellido = panelRegistrarLibro.textFieldSegundoApellidoAutorBuscar.getText().equals("") ? null : panelRegistrarLibro.textFieldSegundoApellidoAutorBuscar.getText();
        String segundoNombre = panelRegistrarLibro.textFieldSegundoNombreAutorBuscar.getText().equals("") ? null : panelRegistrarLibro.textFieldSegundoNombreAutorBuscar.getText();
        List<Autor> listaAutores = new ArrayList<Autor>();
        listaAutores = gestorInformes.obtenerAutores(codigo, primerNombre, primerApellido, segundoNombre, segundoApellido);
        if(!listaAutores.isEmpty()){
            JOptionPane.showMessageDialog(panelRegistrarLibro, "La busqueda SI arrojo resultados", "Buscar", JOptionPane.PLAIN_MESSAGE);
            limpiarTabla(panelRegistrarLibro.tablaAutoresBuscados);
            mostrarAutoresEncontrados(listaAutores);
        }else{
            JOptionPane.showMessageDialog(panelRegistrarLibro, "La busqueda NO arrojo resultados", "Buscar", JOptionPane.PLAIN_MESSAGE);
        }
    }

    private void mostrarAutoresEncontrados(List<Autor> listaAutores) {
        Autor autor;
        for(int i = 0; i < listaAutores.size(); i++){
            if(panelRegistrarLibro.tablaAutoresBuscados.getRowCount() <= i){
                DefaultTableModel tmp = (DefaultTableModel)panelRegistrarLibro.tablaAutoresBuscados.getModel();
                Object fila[] = {"",""};
                tmp.addRow(fila);
            }
            autor = listaAutores.get(i);
            panelRegistrarLibro.tablaAutoresBuscados.setValueAt(autor.getCodigoAutor(), i, 0);
            String nombreCompleto;
            nombreCompleto = autor.getPrimerNombre()+" ";
            if(autor.getSegundoNombre() != null){
                nombreCompleto += autor.getSegundoNombre()+" ";
            }
            nombreCompleto += autor.getPrimerApellido()+" ";
            if(autor.getSegundoApellido() != null){
                nombreCompleto += autor.getSegundoApellido();
            }
            panelRegistrarLibro.tablaAutoresBuscados.setValueAt(nombreCompleto, i, 1);
        }
    }

    public void agregarAutor() {
        Autor autor;
        int codigo = -1;
        int fila = panelRegistrarLibro.tablaAutoresBuscados.getSelectedRow();
        if(fila != -1){
            try {
                codigo = Integer.parseInt(panelRegistrarLibro.tablaAutoresBuscados.getValueAt(fila, 0).toString());
                if(!encontrarAutorAgregado(codigo)){
                    autor = gestorAutor.obtenerAutor(codigo);
                    //crea una fila
                    DefaultTableModel tmp = (DefaultTableModel)panelRegistrarLibro.tablaAutoresAgregados.getModel();
                    Object tupla[] = {"",""};
                    tmp.addRow(tupla);
                    panelRegistrarLibro.tablaAutoresAgregados.setValueAt(autor.getCodigoAutor(), tmp.getRowCount()-1, 0);
                    String nombreCompleto;
                    nombreCompleto = autor.getPrimerNombre()+" ";
                    if(autor.getSegundoNombre() != null){
                        nombreCompleto += autor.getSegundoNombre()+" ";
                    }
                    nombreCompleto += autor.getPrimerApellido()+" ";
                    if(autor.getSegundoApellido() != null){
                        nombreCompleto += autor.getSegundoApellido();
                    }
                    panelRegistrarLibro.tablaAutoresAgregados.setValueAt(nombreCompleto, tmp.getRowCount()-1, 1);
                }
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(panelRegistrarLibro, ex.getMessage(), "Error Agregar Autor", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    public void quitarAutor() {
        int fila = panelRegistrarLibro.tablaAutoresAgregados.getSelectedRow();
        if(fila != -1){
            DefaultTableModel tmp = (DefaultTableModel)panelRegistrarLibro.tablaAutoresAgregados.getModel();
            tmp.removeRow(fila);
        }
    }

    private boolean encontrarAutorAgregado(int codigo) {
        boolean encontrado = false;
        for(int i = 0; i < panelRegistrarLibro.tablaAutoresAgregados.getRowCount(); i++){
            if(codigo == Integer.parseInt(panelRegistrarLibro.tablaAutoresAgregados.getValueAt(i, 0).toString())){
                encontrado = true;
                break;
            }
        }
        return encontrado;
    }

    private List<Autor> obtenerListaAutoresAgregados() {
        List<Autor> listaAutores = new ArrayList<Autor>();
        Autor autor;
        for(int i = 0; i < panelRegistrarLibro.tablaAutoresAgregados.getRowCount(); i++){
            autor = new Autor();
            autor.setCodigoAutor(Integer.parseInt(panelRegistrarLibro.tablaAutoresAgregados.getValueAt(i, 0).toString()));
            listaAutores.add(autor);
        }
        return listaAutores;
    }

    public void buscarArea() {
        int codigo = -1;
        if(panelRegistrarLibro.textFieldCodigoAreaBuscar.getText() != null && !panelRegistrarLibro.textFieldCodigoAreaBuscar.getText().equals("")){
                 codigo = Integer.parseInt(panelRegistrarLibro.textFieldCodigoAreaBuscar.getText());
        }
        String nombre = panelRegistrarLibro.textFieldNombreAreaBuscar.getText().equals("") ? null : panelRegistrarLibro.textFieldNombreAreaBuscar.getText();
        List<Area> listaAreas = new ArrayList<Area>();
        listaAreas = gestorInformes.obtenerAreas(codigo, nombre);
        if(!listaAreas.isEmpty()){
            JOptionPane.showMessageDialog(panelRegistrarLibro, "La busqueda SI arrojo resultados", "Buscar", JOptionPane.PLAIN_MESSAGE);
            limpiarTabla(panelRegistrarLibro.tablaAreasBuscadas);
            mostrarAreasEncontradas(listaAreas);
        }else{
            JOptionPane.showMessageDialog(panelRegistrarLibro, "La busqueda NO arrojo resultados", "Buscar", JOptionPane.PLAIN_MESSAGE);
        }
    }

    private void mostrarAreasEncontradas(List<Area> listaAreas) {
        Area area;
        for(int i = 0; i < listaAreas.size(); i++){
            if(panelRegistrarLibro.tablaAreasBuscadas.getRowCount() <= i){
                DefaultTableModel tmp = (DefaultTableModel)panelRegistrarLibro.tablaAreasBuscadas.getModel();
                Object fila[] = {"",""};
                tmp.addRow(fila);
            }
            area = listaAreas.get(i);
            panelRegistrarLibro.tablaAreasBuscadas.setValueAt(area.getCodigoArea(), i, 0);
            String nombre = area.getNombre();
            panelRegistrarLibro.tablaAreasBuscadas.setValueAt(nombre, i, 1);
        }
    }

    public void agregarArea() {
        Area area;
        int codigo = -1;
        int fila = panelRegistrarLibro.tablaAreasBuscadas.getSelectedRow();
        if(fila != -1 && panelRegistrarLibro.tablaAreasAgregadas.getRowCount() < 1){
            try {
                codigo = Integer.parseInt(panelRegistrarLibro.tablaAreasBuscadas.getValueAt(fila, 0).toString());
                if(!encontrarAreaAgregada(codigo)){
                    area = gestorArea.obtenerArea(codigo);
                    //crea una fila
                    DefaultTableModel tmp = (DefaultTableModel)panelRegistrarLibro.tablaAreasAgregadas.getModel();
                    Object tupla[] = {"",""};
                    tmp.addRow(tupla);
                    panelRegistrarLibro.tablaAreasAgregadas.setValueAt(area.getCodigoArea(), tmp.getRowCount()-1, 0);
                    String nombre = area.getNombre();
                    panelRegistrarLibro.tablaAreasAgregadas.setValueAt(nombre, tmp.getRowCount()-1, 1);
                }
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(panelRegistrarLibro, ex.getMessage(), "Error Agregar Area", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    public void quitarArea() {
        int fila = panelRegistrarLibro.tablaAreasAgregadas.getSelectedRow();
        if(fila != -1){
            DefaultTableModel tmp = (DefaultTableModel)panelRegistrarLibro.tablaAreasAgregadas.getModel();
            tmp.removeRow(fila);
        }
    }

    private boolean encontrarAreaAgregada(int codigo) {
        boolean encontrado = false;
        for(int i = 0; i < panelRegistrarLibro.tablaAreasAgregadas.getRowCount(); i++){
            if(codigo == Integer.parseInt(panelRegistrarLibro.tablaAreasAgregadas.getValueAt(i, 0).toString())){
                encontrado = true;
                break;
            }
        }
        return encontrado;
    }

    private List<Area> obtenerListaAreasAgregadas() {
        List<Area> listaAreas = new ArrayList<Area>();
        Area area;
        for(int i = 0; i < panelRegistrarLibro.tablaAreasAgregadas.getRowCount(); i++){
            area = new Area();
            area.setCodigoArea(Integer.parseInt(panelRegistrarLibro.tablaAreasAgregadas.getValueAt(i, 0).toString()));
            listaAreas.add(area);
        }
        return listaAreas;
    }


    public void agregarPalabra() {
        if(!panelRegistrarLibro.textFieldPalabraBuscar.getText().equals("")){
            PalabraClave palabra;
            palabra = gestorPalabra.buscarPalabra(panelRegistrarLibro.textFieldPalabraBuscar.getText());
            if(palabra == null){
                palabra = new PalabraClave();
                palabra.setNombre(panelRegistrarLibro.textFieldPalabraBuscar.getText());
                gestorPalabra.crearPalabra(palabra);
                palabra = gestorPalabra.buscarPalabra(panelRegistrarLibro.textFieldPalabraBuscar.getText());
            }
            if(!encontrarPalabraAgregada(palabra.getIdPalabra())){
                //crea una fila
                DefaultTableModel tmp = (DefaultTableModel)panelRegistrarLibro.tablaPalabrasAgregadas.getModel();
                Object tupla[] = {"",""};
                tmp.addRow(tupla);
                panelRegistrarLibro.tablaPalabrasAgregadas.setValueAt(palabra.getIdPalabra(), tmp.getRowCount()-1, 0);
                String nombre = palabra.getNombre();
                panelRegistrarLibro.tablaPalabrasAgregadas.setValueAt(nombre, tmp.getRowCount()-1, 1);
            }
        }
    }

    public void quitarPalabra() {
        int fila = panelRegistrarLibro.tablaPalabrasAgregadas.getSelectedRow();
        if(fila != -1){
            DefaultTableModel tmp = (DefaultTableModel)panelRegistrarLibro.tablaPalabrasAgregadas.getModel();
            tmp.removeRow(fila);
        }
    }

    private boolean encontrarPalabraAgregada(int id) {
        boolean encontrado = false;
        for(int i = 0; i < panelRegistrarLibro.tablaPalabrasAgregadas.getRowCount(); i++){
            if(id == Integer.parseInt(panelRegistrarLibro.tablaPalabrasAgregadas.getValueAt(i, 0).toString())){
                encontrado = true;
                break;
            }
        }
        return encontrado;
    }

    private List<PalabraClave> obtenerListaPalabrasAgregadas() {
        List<PalabraClave> listaPalabras = new ArrayList<PalabraClave>();
        PalabraClave palabra;
        for(int i = 0; i < panelRegistrarLibro.tablaPalabrasAgregadas.getRowCount(); i++){
            palabra = new PalabraClave();
            palabra.setIdPalabra(Integer.parseInt(panelRegistrarLibro.tablaPalabrasAgregadas.getValueAt(i, 0).toString()));
            listaPalabras.add(palabra);
        }
        return listaPalabras;
    }


    public void buscarEditorial() {
        String nombre = panelRegistrarLibro.textFieldBuscarEditorial.getText().equals("") ? null : panelRegistrarLibro.textFieldBuscarEditorial.getText();
        List<Editorial> listaEditoriales = new ArrayList<Editorial>();
        listaEditoriales = gestorInformes.obtenerEditoriales(nombre);
        if(!listaEditoriales.isEmpty()){
            JOptionPane.showMessageDialog(panelRegistrarLibro, "La busqueda SI arrojo resultados", "Buscar", JOptionPane.PLAIN_MESSAGE);
            limpiarTabla(panelRegistrarLibro.tablaEditorialesBuscadas);
            mostrarEditorialesEncontradas(listaEditoriales);
        }else{
            JOptionPane.showMessageDialog(panelRegistrarLibro, "La busqueda NO arrojo resultados", "Buscar", JOptionPane.PLAIN_MESSAGE);
        }
    }

    private void mostrarEditorialesEncontradas(List<Editorial> listaEditoriales) {
        Editorial editorial;
        for(int i = 0; i < listaEditoriales.size(); i++){
            if(panelRegistrarLibro.tablaEditorialesBuscadas.getRowCount() <= i){
                DefaultTableModel tmp = (DefaultTableModel)panelRegistrarLibro.tablaEditorialesBuscadas.getModel();
                Object fila[] = {"",""};
                tmp.addRow(fila);
            }
            editorial = listaEditoriales.get(i);
            panelRegistrarLibro.tablaEditorialesBuscadas.setValueAt(editorial.getCodigoEditorial(), i, 0);
            String nombre = editorial.getNombre();
            panelRegistrarLibro.tablaEditorialesBuscadas.setValueAt(nombre, i, 1);
        }
    }

    public void seleccionarEditorial() {
        int fila = panelRegistrarLibro.tablaEditorialesBuscadas.getSelectedRow();
        if(fila != -1){
            String codigo = panelRegistrarLibro.tablaEditorialesBuscadas.getValueAt(fila, 0).toString();
            panelRegistrarLibro.textFieldEditorial.setText(codigo);
        }
    }


    public void seleccionarFecha() {
        int dia, mes, ano;
        dia = panelRegistrarLibro.calendario.getDayChooser().getDay();
        mes = panelRegistrarLibro.calendario.getMonthChooser().getMonth()+1;
        ano = panelRegistrarLibro.calendario.getYearChooser().getYear();
        panelRegistrarLibro.textFieldAnoPublicacion.setText(dia+"/"+mes+"/"+ano);
        fechaPublicacion = panelRegistrarLibro.calendario.getDate();
    }


    public void registrarLibro() {
        Libro libro = null;
        try{
            List<Autor> listaAutores = obtenerListaAutoresAgregados();
            List<Area> listaAreas = obtenerListaAreasAgregadas();
            List<PalabraClave> listaPalabras = obtenerListaPalabrasAgregadas();
            if(!listaAreas.isEmpty() && !listaAutores.isEmpty() && !listaPalabras.isEmpty()){
                //Atributos propios de un libro
                Long isbn = Long.parseLong(panelRegistrarLibro.textFieldISBN.getText());
                int codigoEditorial = Integer.parseInt(panelRegistrarLibro.textFieldEditorial.getText());
                String titulo = panelRegistrarLibro.textFieldTitulo.getText();
                Date anoPublicacion = fechaPublicacion;
                String idioma = panelRegistrarLibro.textFieldIdioma.getText();
                //crea el libro
                libro = new Libro();
                libro.setActivo(true);
                libro.setAnoPublicacion(anoPublicacion);
                libro.setCantidadBusquedas(0);
                libro.setCodigoEditorial(codigoEditorial);
                libro.setIdioma(idioma);
                libro.setIsbn(isbn);
                libro.setTitulo(titulo);
                libro.setListaAreas(listaAreas);
                libro.setListaAutores(listaAutores);
                libro.setListaPalabrasClave(listaPalabras);
                //valida los datos del libro
                new VBiblioteca(libro);
                //crea el nuevo libro
                gestorLibro.crearLibro(libro);
                //si no ocurren exepciones
                JOptionPane.showMessageDialog(panelRegistrarLibro, "El nuevo libro ha sido creado con exito", "Registrar Libro", JOptionPane.PLAIN_MESSAGE);
                limpiar();
            } else {
                JOptionPane.showMessageDialog(panelRegistrarLibro, "Un libro debe tener Autores, Areas de conocimiento, Palabras Clave", "Datos Incompletos", JOptionPane.INFORMATION_MESSAGE);
            }
        }  catch(NumberFormatException ex) {
            JOptionPane.showMessageDialog(panelRegistrarLibro, "Debe ingresar un numero de ISBN y codigo de editorial", "Error Codigo", JOptionPane.INFORMATION_MESSAGE);
        } catch (EntityExistsException ex) {
            JOptionPane.showMessageDialog(panelRegistrarLibro, "Ya existe un libro con ISBN "+libro.getIsbn(), "Error Codigo", JOptionPane.INFORMATION_MESSAGE);
        } catch (RollbackException ex) {
            JOptionPane.showMessageDialog(panelRegistrarLibro, "Ya existe un libro con ISBN "+libro.getIsbn(), "Error Codigo", JOptionPane.INFORMATION_MESSAGE);
        } catch (VBiblioteca ex) {
            JOptionPane.showMessageDialog(panelRegistrarLibro, ex.getMessage(), "Error Datos", JOptionPane.INFORMATION_MESSAGE);
        }
    }

    private void limpiar() {
        limpiarTabla(panelRegistrarLibro.tablaAreasAgregadas);
        limpiarTabla(panelRegistrarLibro.tablaAreasBuscadas);
        limpiarTabla(panelRegistrarLibro.tablaAutoresAgregados);
        limpiarTabla(panelRegistrarLibro.tablaAutoresBuscados);
        limpiarTabla(panelRegistrarLibro.tablaEditorialesBuscadas);
        limpiarTabla(panelRegistrarLibro.tablaPalabrasAgregadas);
        panelRegistrarLibro.textFielCodigoAutorBuscar.setText("");
        panelRegistrarLibro.textFieldAnoPublicacion.setText("");
        panelRegistrarLibro.textFieldBuscarEditorial.setText("");
        panelRegistrarLibro.textFieldCodigoAreaBuscar.setText("");
        panelRegistrarLibro.textFieldEditorial.setText("");
        panelRegistrarLibro.textFieldISBN.setText("");
        panelRegistrarLibro.textFieldIdioma.setText("");
        panelRegistrarLibro.textFieldNombreAreaBuscar.setText("");
        panelRegistrarLibro.textFieldPalabraBuscar.setText("");
        panelRegistrarLibro.textFieldPrimerApellidoAutorBuscar.setText("");
        panelRegistrarLibro.textFieldPrimerNombreAutorBuscar.setText("");
        panelRegistrarLibro.textFieldSegundoApellidoAutorBuscar.setText("");
        panelRegistrarLibro.textFieldSegundoNombreAutorBuscar.setText("");
        panelRegistrarLibro.textFieldTitulo.setText("");
    }

    public void limpiarTabla(JTable tabla) {
        for(int i = 0; i < tabla.getRowCount(); i++){
            DefaultTableModel tmp = (DefaultTableModel)tabla.getModel();
            tmp.removeRow(i);
            if(tmp.getRowCount()>0){
                limpiarTabla(tabla);
            }
        }
    }
}
